/******************************************************************************
 *
 * Copyright:
 *    (C) 2000 - 2005 Embedded Artists AB
 *
 *****************************************************************************/


#include "testLcd.h"

#define LCD_DATA      0x00ff0000  //P1.16-P1.23 data input/ output
#define LCD_E         0x02000000  //P1.25 enable signal
#define LCD_RW        0x00400000  //P0.22 RW=0 register write RW=1 register read
#define LCD_RS        0x01000000  //P1.24 RS=0 Instruction register RS=1 data register
#define LCD_BACKLIGHT 0x40000000  //P0.30


char firstColumns [] = {0, 64, 16, 16+64};


/*****************************************************************************
 *
 * Description:
 *    Function initialize 2x16 LCD screen
 *
 ****************************************************************************/
void
initLCD(void)
{
	IODIR1 |= (LCD_DATA | LCD_E | LCD_RS); // Set pins to output
	IOCLR1  = (LCD_DATA | LCD_E | LCD_RS); // set pins to low state

	IODIR0 |= LCD_RW;
	IOCLR0  = LCD_RW;

	IODIR0 |= LCD_BACKLIGHT;
	IOCLR0  = LCD_BACKLIGHT;
}

/*****************************************************************************
 *
 * Description:
 *   Function delay execution for 37us.
 *
 ****************************************************************************/
static void
delay37us(void)
{
	volatile tU32 i;

	//Temp test for 140 uS delay
	for(i=0; i<6*2500; i++)
		asm volatile (" nop"); //delay 15 ns x 2500 = about 37 us delay
}

/*****************************************************************************
 *
 * Description:
 *  Writes data to LCD screen
 * Params:
 *    [in] reg - if reg ==0 write command else write character on creen
 *    [in] data - data to write
 *
 ****************************************************************************/
static void
writeLCD(tU8 reg, tU8 data)
{
	volatile tU8 i;

	// if reg == 0 we send command
	// else we write on screen
	if (reg == 0)
		IOCLR1 = LCD_RS;
	else
		IOSET1 = LCD_RS;

	IOCLR0 = LCD_RW; // set to write
	IOCLR1 = LCD_DATA; // clean data
	IOSET1 = ((tU32)data << 16) & LCD_DATA; // data to registry


	IOSET1 = LCD_E; // set controll signal to ON

	// necessary delays
	for(i=0; i<16; i++){
		asm volatile (" nop"); //delay 15 ns x 16 = about 250 ns delay
	}

	IOCLR1 = LCD_E; // set controll signal to OFF

	for(i=0; i<16; i++){
		asm volatile (" nop"); //delay 15 ns x 16 = about 250 ns delay
	}
}

/*****************************************************************************
 *
 * Description:
 *    Turns LCD backlight ON or OFF
 * Params:
 *    [in] onOFF - if true turn backlight ON else turn it OFF
 *
 ****************************************************************************/
void
lcdBacklight(tU8 onOff)
{
	if (onOff == TRUE)
		IOSET0 = LCD_BACKLIGHT;
	else
		IOCLR0 = LCD_BACKLIGHT;
}

/*****************************************************************************
 *
 * Description:
 *   Writes string on LCD screen
 * Params:
 *    [in] string - string to write
 *
 ****************************************************************************/
static void
writeString(char * string){
	while(*string > 0)
	{
		writeLCD(1,*string++);
		delay37us();
	}
}

/*****************************************************************************
 *
 * Description:
 *   Prints integer on screen
 *
 ****************************************************************************/
tS16  print(tS16 * figure) {
	tS16 ret = 1;
	if (*figure < 0) {
		writeString("-");
		*figure = -*figure;
		ret++;
	}
	tS16 digit = *figure % 10;
	*figure = *figure / 10;
	if (*figure > 0 || *figure % 10 != 0)
		ret += print(figure);

	writeLCD(1, digit + '0');
	delay37us();
	return ret;
}
/*****************************************************************************
 *
 * Description:
 *   Prints integer on screen
 *
 ****************************************************************************/
tS16 printInt(tS16 figure) {
	tS16 tmp = figure;
	return print(&tmp);
}

/*****************************************************************************
 *
 * Description:
 *    A process entry function 
 *    Writes current temperature and depth on screen
 *
 ****************************************************************************/
void
lcdPrint(tS16 temp, int depth)
{

	//function set
	writeLCD(0, 0x30);// 0011 0000 - 8 bits input , one line writing, 5x7 points
	osSleep(1);
	writeLCD(0, 0x30);
	delay37us();
	writeLCD(0, 0x30);
	delay37us();

	//function set
	writeLCD(0, 0x38);// 0011 0000 - 8 bit input, one line writing, 5x10 points
	delay37us();

	//display off
	writeLCD(0, 0x08);
	delay37us();

	//display clear
	writeLCD(0, 0x01);
	osSleep(1); //actually only 1.52 mS needed

	//display control set
	writeLCD(0, 0x06);// moving direction of cursor
	osSleep(1);

	//display control set
	writeLCD(0, 0x0c);
	delay37us();

	//cursor home
	writeLCD(0, 0x02);
	osSleep(1);
	lcdBacklight(TRUE);
	// cleen LCD
	writeLCD(0,1);
	osSleep(1);

	writeString("Temperatura ");
	printInt(temp);

	writeString("'C");


	// to next row
	writeLCD(0,0x80 | 0x40);
	delay37us();

	writeString("Glebokosc ");
	printInt(depth);
	writeString("m");


}
